/*
    Copyright  Louis CHEREL cherel.louis@gmail.com  
    This file is part of Agenda de l'Efrei.

    Agenda de l'Efrei is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Agenda de l'Efrei is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Agenda de l'Efrei.  If not, see <http://www.gnu.org/licenses/>.
 */

package fr.efrei.AgendaEfrei;

//import android.app.ActionBar;
import android.content.*;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.*;
import android.util.Xml;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

public class WeeksUpdater extends AsyncTask<Void,Void,Void> {
//public class WeeksUpdater extends AsyncTask<ActionBar,Void,String> {
    private Context parent;
    private final String ns = null; // on n'utilise pas de namespaces
    //protected ActionBar mAc; //debug
    WeeksUpdater(Context c){
        parent = c;
    }
    
    /** Called when the activity is first created. */
    protected Void doInBackground(Void...v){
//    protected String doInBackground(ActionBar...ac){
        MainActivity.setIsWeeksUpdaterLaunched(true);
        //mAc = ac[0];
        boolean isUpdateNecessary=false;
        
        //String debug="";
        
        File fileTest = new File(parent.getFilesDir(),"weeks");
        char[] buffer_file = new char[20000];
        String weeksFileContent;
        if(fileTest.exists())
        {
            try{
                GregorianCalendar c = new GregorianCalendar();
                int today = c.get(c.DAY_OF_WEEK);
                long now = c.getTimeInMillis();
                long milli_today = ((c.get(c.HOUR_OF_DAY)*60+c.get(c.MINUTE))*60+c.get(c.SECOND))*1000+c.get(c.MILLISECOND);
                FileReader file = new FileReader(parent.getFilesDir()+"weeks");
                while(!file.ready()){}
                file.read(buffer_file);
                weeksFileContent = new String(buffer_file);
                Pattern pattern = Pattern.compile("<update>([0-9]*)</update>", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                Matcher matcher = pattern.matcher(weeksFileContent);
                matcher.find();
                weeksFileContent =  matcher.group(1);
                long updated=Long.parseLong(weeksFileContent);
                
                //debug=String.valueOf(c.getTimeInMillis()-updated);
                if((today == c.SATURDAY && (milli_today>=66600000)  && (updated<(now-milli_today+66600000)) )
                  || ((today>=c.SUNDAY) && (updated+(today-1)*86400000+milli_today)<now)
                  )
                {
                    isUpdateNecessary=true;

                }
            }catch(Exception e){
                isUpdateNecessary=true;
            }
        }
        else{
            isUpdateNecessary=true;
        }
        
        
        //wv=w[0]; //debug
        if(isUpdateNecessary)
        {
            char[] buffer_url = new char[60000];
            String returnField;
            if(isNetworkAvailable()){
                try {
                    URL page_data = new URL("http://edt.bde.assos.efrei.fr/?s=-1&d=-1&p=1");
                    // on télécharge la page
                    InputStream in = page_data.openConnection().getInputStream();
                    InputStreamReader html_content = new InputStreamReader(in);

                    // tant que le contenu n'est pas prêt... on met tout dans le buffer
                    // puis on retourne le buffer au fil conducteur
                    while(!html_content.ready()) {}
                    html_content.read(buffer_url,0,59990);
                    in.close();
                    returnField = new String(buffer_url);

                    // on nettoie tout ce fichier HTML mal codé
                    Pattern pattern1 = Pattern.compile("<meta(.*)utf-8\">", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern1bis = Pattern.compile("<meta(.*)root\">", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern1ter = Pattern.compile("<meta(.*)ieux\">", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern2 = Pattern.compile("([A-Z]{2,20})=([[A-Z][0-9]]{1,20})", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
                    Pattern pattern3 = Pattern.compile("<input(.*)\"Afficher\">", Pattern.DOTALL|Pattern.COMMENTS);
                    returnField = pattern1.matcher(returnField).replaceAll("<meta$1utf-8\"/>");
                    returnField = pattern1bis.matcher(returnField).replaceAll("");
                    returnField = pattern1ter.matcher(returnField).replaceAll("");
                    returnField = pattern2.matcher(returnField).replaceAll("$1=\"$2\"");
                    returnField = pattern3.matcher(returnField).replaceAll("");

                    parseHtml(returnField);
                    //return parseHtml(returnField);

                } catch(Exception e){
                    //return "[5] "+e.toString();
                }
            }
        }
        MainActivity.setIsWeeksUpdaterLaunched(false); 
        return null;
        //return debug;
    }
    /*
    @Override
    protected void onPostExecute(String s) {
        mAc.setTitle("d "+s);
        //wv.loadData(s, "text/plain", null);
    }*/
    
    public boolean isNetworkAvailable(){
        boolean isAvailable;
        ConnectivityManager connectivityMgr =(ConnectivityManager) parent.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityMgr.getActiveNetworkInfo();
        if(networkInfo!=null && networkInfo.isAvailable()){
            isAvailable = true;
        }
        else {
            isAvailable = false;
        }
        return isAvailable;
    }
    
    private String parseHtml(String in) throws XmlPullParserException,IOException {
        InputStream iS=null;
        try{
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,false);

            iS = new ByteArrayInputStream(in.getBytes());
            parser.setInput(iS,null);
            parser.nextTag();
            return readHtml(parser);
        } catch (Exception e){ return "parseHtml "+e.toString();}
        finally{
            if(iS!=null){
                iS.close();
            }
        }
    }



    private String readHtml(XmlPullParser parser) throws XmlPullParserException,IOException {
        
        boolean isSelectAboutWeeks = false, stopParsing=false;
        int i=0;
        String[] weeks = new String[5];
        String[] nbrs  = new String[5];
        Pattern pattern = Pattern.compile("Semaine ", Pattern.MULTILINE | Pattern.DOTALL|Pattern.COMMENTS);
        try{
            parser.require(XmlPullParser.START_TAG, ns, "html");
            
            
            while(parser.next() != XmlPullParser.END_DOCUMENT && !stopParsing)
            {
                if (parser.getEventType() != XmlPullParser.START_TAG)
                {    
                    if(parser.getEventType() == XmlPullParser.END_TAG && parser.getName().equals("select"))
                    {
                            isSelectAboutWeeks=false;
                    }
                    continue;
                }

                String name = parser.getName();
                
                if(name.equals("select")) 
                {
                    isSelectAboutWeeks = parser.getAttributeValue(ns, "name").equals("s")?true:false;
                }
                else if(name.equals("option"))
                {
                    if(isSelectAboutWeeks)
                    {
                        nbrs[i] = parser.getAttributeValue(ns, "value");
                        if(parser.next() == XmlPullParser.TEXT)
                        {
                            weeks[i] = parser.getText();
                            weeks[i] = pattern.matcher(weeks[i]).replaceFirst("");
                            i++;
                        }
                    }
                    else{
                        stopParsing=true;
                    }
                }
            }
        }
        catch(Exception e){
            return "readHtml " + e.toString();
        }
        return writeToXml(weeks,nbrs,i);
    }
    
    private String writeToXml(String[] weeks,String[] nbrs,int i) throws IOException{
        XmlSerializer s = Xml.newSerializer();
        try{
            File file = new File(parent.getFilesDir(),"weeks");
            
            if(file.exists()){
                file.delete();
            }
            file.createNewFile();
            FileOutputStream fOs = new FileOutputStream(parent.getFilesDir()+"weeks",false);
            s.setOutput(fOs,null);
            s.startDocument(ns, false);
            s.startTag(ns, "weeks");
            s.startTag(ns, "update");
            GregorianCalendar calendar = new GregorianCalendar();
            s.text(String.valueOf(calendar.getTimeInMillis()));
            s.endTag(ns,"update");
            for(int j=0;j<i;j++){
                s.startTag(ns,"week");
                s.startTag(ns,"number");
                s.text(nbrs[j]);
                s.endTag(ns, "number");
                s.startTag(ns, "name");
                s.text(weeks[j]);
                s.endTag(ns, "name");
                s.endTag(ns, "week");
            }
            s.endTag(ns, "weeks");
            s.flush();
            s.endDocument();
            return "Good";
            
        } catch(Exception e){
            return "writeToXml "+e.toString();
        }
    }

}
